<?php
/**
 * Created by PhpStorm.
 * User: 小灰灰
 * Date: 2023-11-16
 * Time: 18:10:49
 * Info: 前端模版标签
 */

namespace app\index\taglib;

use think\template\TagLib;

class Cms extends TagLib
{

    /**
     * 定义标签列表
     */
    protected $tags = [
        // 标签定义： attr 属性列表 close 是否闭合（0 或者1 默认1） alias 标签别名 level 嵌套层次
        'close'       => ['attr' => 'time,format', 'close' => 0],
        //闭合标签，默认为不闭合
        'open'        => ['attr' => 'name,type', 'close' => 1],
        // 通用导航信息
        'nav'         => ['attr' => 'id,field,limit,order,item,key', 'close' => 1],
        // 通用栏目信息
        'cate'        => ['attr' => 'id,field', 'close' => 0],
        // 通用位置信息
        'position'    => ['attr' => 'catid,symbol,class,currentstyle,isclick', 'close' => 0],
        // 获取文章列表
        'lists'       => ['attr' => 'catid,item,field,model_id,num,order,key,order,insub', 'close' => 1],
        // 内容列表标签
        'content'     => [
            'attr'  => 'atid,field,model_id,order,num,where,page,id,empty,mod,key,cache,tagid,flag,inlist,aid,aids,filter',
            'close' => 1
        ],
        // 获取友情链接
        'link'        => ['attr' => 'group,logo,order', 'close' => 1],
        // 获取轮播图
        'slide'       => ['attr' => 'group,order', 'close' => 1],
        // 生成列表分页页码标签 // 设置分页格式
        'contentpage' => [
            'attr'  => 'item,size,home,pre,next,last,jump,mobile_item,name,info,emptxt,hasemp',
            'close' => 0
        ],
        // 上一篇
        'pre'         => ['attr' => 'catid,id,target,msg,field,len,dot', 'close' => 0],
        // 下一篇
        'next'        => ['attr' => 'catid,id,target,msg,field,len,dot', 'close' => 0],
        // 获取数据库数据
        'query'       => [
            'attr'  => 'id,sql,cache,empty,mod,key,num,table,field,alias,where,order,tableid',
            'close' => 1
        ],
        // 输出筛选字段
        'filter'      => ['attr' => 'id,currentstyle,multiple,field,alltxt', 'close' => 1],
    ];

    /**
     * 这是一个闭合标签的简单演示
     */
    public function tagClose($tag)
    {
        $format = empty($tag['format']) ? 'Y-m-d H:i:s' : $tag['format'];
        $time   = empty($tag['time']) ? time() : $tag['time'];
        $parse  = '<?php ';
        $parse  .= 'echo date("'.$format.'",'.$time.');';
        $parse  .= ' ?>';

        return $parse;
    }

    /**
     * 这是一个非闭合标签的简单演示
     */
    public function tagOpen($tag, $content)
    {
        $type  = empty($tag['type']) ? 0 : 1; // 这个type目的是为了区分类型，一般来源是数据库
        $name  = $tag['name']; // name是必填项，这里不做判断了
        $parse = '<?php ';
        $parse .= '$test_arr=[[1,3,5,7,9],[2,4,6,8,10]];'; // 这里是模拟数据
        $parse .= '$__LIST__ = $test_arr['.$type.'];';
        $parse .= ' ?>';
        $parse .= '{volist name="__LIST__" id="'.$name.'"}';
        $parse .= $content;
        $parse .= '{/volist}';

        return $parse;
    }

    //获取导航信息
    public function tagNav($tag, $content)
    {
        $item  = $tag['item'] ?? 'vo';//循环变量名
        $key   = $tag['key'] ?? 'key';//循环key
        $field = $tag['field'] ?? '';
        $id    = $tag['id'] ?? 0;
        $limit = ! empty($tag['limit']) ? (int)$tag['limit'] : 0;
        $order = ! empty($tag['order']) ? $tag['order'] : "sort asc,id asc";
        $str   = '<?php'."\r\n";
        $str   .= '$__cateList__ = (new \app\common\model\Category)->tpCateListTree('.$id.',"'.$field.'","'.$limit.'","'.$order.'");'."\r\n";
        $str   .= '?>';
        $str   .= '{foreach name="__cateList__" id="'.$item.'" key="'.$key.'"}';
        $str   .= $content;
        $str   .= '{/foreach}';

        return $str;
    }

    /**
     * 通用栏目信息
     * 用于根据id获取栏目的某个字段内容
     *
     * @param $tag
     */
    public function tagCate($tag)
    {
        $id    = $tag['id'] ?? cmf_get_cate_id();
        $field = ! empty($tag['field']) ? $tag['field'] : 'name';
        $str   = '<?php ';
        $str   .= '$__CATE__ = (new \app\common\model\Category)->getCateInfo('.$id.',"'.$field.'");';
        $str   .= 'if(!empty($__CATE__) && $__CATE__[\'code\'] != 0){';
        $str   .= 'echo $__CATE__[\'data\'];';
        $str   .= '}';
        $str   .= '?>';

        return $str;
    }

    // 获取文章列表
    public function tagLists($tag, $content)
    {
        $cid      = $tag['cid'] ?? '';
        $tid      = $tag['tid'] ?? '';
        $catid    = $tag['catid'] ?? '';    //所属栏目
        $model_id = $tag['model_id'] ?? '';    //模型ID
        $flag     = $tag['flag'] ?? '';    //属性
        $field    = $tag['field'] ?? '';    //输出字段
        $thumb    = $tag['thumb'] ?? 0;    //是否有缩略图
        $num      = $tag['num'] ?? 10;   //数量
        $order    = $tag['order'] ?? "sort asc,update_time desc"; //排序
        $item     = $tag['item'] ?? 'vo';//循环变量名
        $key      = $tag['key'] ?? 'key';//循环key
        $insub    = $tag['insub'] ?? 1;//需要与catid同时使用，默认包含下级文章
        $page     = $tag['page'] = $tag['page'] ?? 0;//是否开启分页
        $parse    = <<<parse
        <?php
            \$is_page = $page;
            \$__ACTIONS_ITEMS__ = (new \app\common\model\Content())->lists('{$catid}','{$model_id}','{$field}',{$thumb},{$num},'{$order}','{$flag}','{$insub}',\$cid);
            if(\$__ACTIONS_ITEMS__->isEmpty() === true){
                echo "<div id=\"no_data\">暂无数据</div>";
            }
        ?>
        {foreach name="__ACTIONS_ITEMS__" id="{$item}" key="{$key}"}
        {$content}
        {/foreach}
        parse;

        return $parse;
    }

    /**
     * 内容模型标签
     *
     * @param $tag
     * @param $content
     *
     * @return string
     */
    public function tagContent($tag, $content)
    {
        // 栏目id
        $tag['catid'] = isset($tag['catid']) ? $tag['catid'] : '';
        $tag['model'] = isset($tag['model']) ? $tag['model'] : '';
        $tag['aid']   = isset($tag['aid']) ? $tag['aid'] : '';
        $tag['aids']  = isset($tag['aids']) ? $tag['aids'] : '';
        $tag['item']  = ! empty($tag['item']) ? $tag['item'] : 'vo';
        $tag['empty'] = ! empty($tag['empty']) ? $tag['empty'] : '';
        $tag['where'] = ! empty($tag['where']) ? $this->parseCondition($tag['where']) : '';
        $tag['page']  = $tag['page'] ?? 0;
        $tag['num']   = isset($tag['num']) ? $tag['num'] : '10';
        $tag['field'] = $tag['field'] ?? '*';
        $this->autoBuildVar($tag['num']);
        $tag['key'] = empty($tag['key']) ? '' : 'key="'.$tag['key'].'"';
        $tag['mod'] = isset($tag['mod']) && is_numeric($tag['mod']) ? 'mod="'.$tag['mod'].'"' : '';
        // 是否包含下级
        $tag['insub'] = ! isset($tag['insub']) || ($tag['insub'] != 1 && $tag['insub'] != 0) ? 1 : $tag['insub'];
        // 是否开启筛选
        $tag['filter'] = isset($tag['filter']) && $tag['filter'] != 1 ? 0 : 1;
        // ajax分页
        $tag['tagid'] = empty($tag['tagid']) ? '' : $tag['tagid'];
        // 分页变量
        $grs = 'page_'.get_random_str(8);

        $this->autoBuildVar($tag['catid']);
        $this->autoBuildVar($tag['model']);
        $this->autoBuildVar($tag['aid']);
        $this->autoBuildVar($tag['aids']);

        $parseStr = '<?php'."\r\n";
        $parseStr .= '$__LISTS__=[];'."\r\n";
        $parseStr .= '$'.$grs.'=null;'."\r\n";
        $parseStr .= '$__CONTENTTAG__ = '.self::arrToHtml($tag).';'."\r\n";
        $parseStr .= '$__LISTS__ = (new \app\index\taglib\huicms\TagContent())->switchController($__CONTENTTAG__, $'.$grs.',$Cate??"");'."\r\n";
        if ($tag['page']) {
            $parseStr .= '$__page__ = $'.$grs.';'."\r\n";
        }
        $parseStr .= '?>';

        $parseStr .= '{volist name="__LISTS__" id="'.$tag['item'].'" '.$tag['key'].' '.$tag['mod'].' empty="'.$tag['empty'].'"}';
        if ($tag['mod']) {
            $parseStr .= '{php}$mod=$mod+1;{/php}';
        }
        $parseStr .= $content;
        $parseStr .= '{/volist}';

        return $parseStr;
    }

    /**
     * 设置分页格式
     * home-首页,pre-上一页,pageno-页码,next-下一页,last-尾页,info-数量信息,jump-跳转页码
     * size 属性指定多少个页码则显示省略号。至少6个。
     *
     * @param $tag
     *
     * @return string
     */
    public function tagContentpage($tag)
    {
        $tag['item'] = empty($tag['item']) ? 'pre,pageno,next' : $tag['item'];
        $tag['name'] = empty($tag['name']) ? '$__page__' : $this->autoBuildVar($tag['name']);
        //$tag['dots'] = isset($tag['dots']) && $tag['dots']==1 ? 0 : 1; // 是否显示 1-隐藏，0-显示
        if (request()->isMobile() && ! empty($tag['mobile_item'])) {
            $tag['item'] = $tag['mobile_item'];
        }

        $parseStr = '<?php'."\r\n";
        $parseStr .= 'if (!empty('.$tag['name'].')) : '."\r\n";
        $parseStr .= '  $params = [];if(isset($cate)) : $params = get_config("url_mode")==1?$cate:["catname"=>$cate["name"]];endif;'."\r\n";
        $parseStr .= '  if(isset($Info) && get_config("url_mode")==1 && isset($Info["id"])) : $params["aid"] = $Info["id"];endif;'."\r\n";
        $parseStr .= '  if(isset($Info) && get_config("url_mode")==2 && isset($Info["id"])) : $params["id"] = $Info["id"];endif;'."\r\n";
        $parseStr .= '  if (!\app\common\library\Bootstrap::getDiyUrl()) {'."\r\n";
        $parseStr .= '  $params = $params->toArray();';
        $parseStr .= '  \app\common\library\Bootstrap::diyUrlResolver(function ($page, $options) use($params) {'."\r\n";
        $parseStr .= '      $params = array_merge($params, $options["query"])'.";\r\n";
        $parseStr .= '      $params["page"] = $page;'."\r\n";
        $parseStr .= '      $GLOBALS["JUMP_query"] = $params;'."\r\n";
        $parseStr .= '      $ruleParam = $options["rule"]??[];'."\r\n";
        $parseStr .= '      return index_url($options["path"],$params,true,false,"",$ruleParam,$options["query"]);'."\r\n";
        $parseStr .= '  });'."\r\n";
        $parseStr .= '  }'."\r\n";
        $parseStr .= 'echo is_object('.$tag['name'].')?'.$tag['name'].'->render('.self::arrToHtml($tag).'):"";'."\r\n";
        $parseStr .= 'endif; ?>';

        return $parseStr;
    }

    //获取友情链接
    public function tagLink($tag, $content)
    {
        $item     = $tag['item'] ?? 'vo';//循环变量名
        $key      = $tag['key'] ?? 'key';//循环key
        $group_id = $tag['group'] ?? '';
        $logo     = $tag['logo'] ?? '';
        $order    = ! empty($tag['order']) ? $tag['order'] : "sort asc";
        $limit    = $tag['limit'] ?? 10;
        $where    = "1=1";
        if ( ! empty($group_id)) {
            $where .= " and group_id =$group_id";
        }
        if ( ! empty($logo)) {
            $where .= " and logo!=''";
        }
        $str = '<?php'."\r\n";
        $str .= '$__LINK__ = (new \app\common\model\Links)->getList(1,'.$limit.',"'.$order.'","'.$where.'");'."\r\n";
        $str .= '?>';
        $str .= '{foreach name="__LINK__" id="'.$item.'" key="'.$key.'"}';
        $str .= $content;
        $str .= '{/foreach}';

        return $str;
    }

    // 轮播图
    public function tagSlide($tag, $content)
    {
        $item     = $tag['item'] ?? 'vo';//循环变量名
        $key      = $tag['key'] ?? 'key';//循环key
        $group_id = $tag['group'] ?? '';
        $order    = ! empty($tag['order']) ? $tag['order'] : "sort asc";
        $limit    = $tag['limit'] ?? 10;
        $where    = "1=1";
        if ( ! empty($group_id)) {
            $where .= " and group_id =$group_id";
        }
        $str = '<?php'."\r\n";
        $str .= '$__SLIDE__ = (new \app\common\model\Slide)->getList(1,'.$limit.',"'.$order.'","'.$where.'");'."\r\n";
        $str .= '?>';
        $str .= '{foreach name="__SLIDE__" id="'.$item.'" key="'.$key.'"}';
        $str .= $content;
        $str .= '{/foreach}';

        return $str;
    }

    /**
     * 面包屑导航，catid,symbol-间隔符号,style-a标签的class
     *
     * @param $tag
     *
     * @return string
     */
    public function tagPosition($tag)
    {
        $tag['symbol']       = $tag['symbol'] ?? ' > ';
        $tag['class']        = $tag['class'] ?? '';
        $tag['currentstyle'] = $tag['currentstyle'] ?? 'active';
        $tag['isclick']      = $tag['isclick'] ?? '0';

        if ( ! empty($tag['catid'])) {
            $this->autoBuildVar($tag['catid']);
        }

        $parseStr = '<?php'."\r\n";
        $parseStr .= '  $__BreadcrumbPARAM__ = [];'."\r\n";

        if (empty($tag['catid'])) {
            $parseStr .= '$__BreadcrumbPARAM__ = '.self::arrToHtml($tag).';'."\r\n";
            $parseStr .= 'if (empty($__BreadcrumbPARAM__["catid"])): '."\r\n";
            $parseStr .= '   $__BreadcrumbPARAM__["catid"]=$Cate["id"]??"";'."\r\n";
            $parseStr .= 'endif;'."\r\n";
        } else {
            $parseStr .= 'if (isset('.$tag['catid'].')): '."\r\n";
            $parseStr .= '$__BreadcrumbPARAM__ = '.self::arrToHtml($tag).';'."\r\n";
            $parseStr .= 'endif;'."\r\n";
        }
        $parseStr .= '  echo (new \app\common\model\Category)->getBreadcrumb($__BreadcrumbPARAM__);'."\r\n";
        $parseStr .= '?>';

        return $parseStr;
    }

    // 详情上一篇
    public function tagPre($tag)
    {
        // 栏目ID
        $tag['catid'] = ! empty($tag['catid']) ? $tag['catid'] : '';
        // 文章ID
        $tag['id'] = ! empty($tag['id']) ? $tag['id'] : '';
        // 显示字段
        $tag['field'] = ! empty($tag['field']) ? $tag['field'] : 'title';
        // 当没有内容时的提示语
        $tag['msg'] = ! empty($tag['msg']) ? lang($tag['msg']) : lang('No more');
        // 标题长度
        $tag['len'] = ! empty($tag['len']) ? $tag['len'] : '';
        // 长度超过限制长度加...
        $tag['dot'] = isset($tag['dot']) ? $tag['dot'] : '';
        // 是否新窗口打开
        $tag['target'] = empty($tag['target']) ? '' : $tag['target'];
        // 上一篇下一篇
        $tag['type'] = ! empty($tag['type']) ? $tag['type'] : 'pre';

        $this->autoBuildVar($tag['catid']);

        $parseStr = '<?php'."\r\n";
        $parseStr .= '$__TAGPARAM__ = '.self::arrToHtml($tag).";\r\n";
        $parseStr .= 'if(empty($__TAGPARAM__["catid"])):'."\r\n";
        $parseStr .= '  $__TAGPARAM__["catid"]=$Cate["id"]??"";'."\r\n";
        $parseStr .= 'endif;'."\r\n";
        $parseStr .= 'if(empty($__TAGPARAM__["id"])):'."\r\n";
        $parseStr .= '  $__TAGPARAM__["id"]=$Info["id"]??"";'."\r\n";
        $parseStr .= 'endif;'."\r\n";
        $parseStr .= '$__TITLE__ = (new \app\index\taglib\huicms\TagPreNext())->preNextHtml($__TAGPARAM__);'."\r\n";

        $parseStr .= 'if ($__TITLE__) : '."\r\n";
        $parseStr .= '  echo $__TITLE__;'."\r\n";
        $parseStr .= 'else: '."\r\n";
        $parseStr .= '  echo "'.$tag['msg'].'"; '."\r\n";
        $parseStr .= 'endif; ?>';

        return $parseStr;
    }

    // 详情下一篇
    public function tagNext($tag)
    {
        $tag['type'] = 'next';

        return $this->tagPre($tag);
    }

    /**
     * 原生SQL查询
     *
     * @param $tag
     * @param $content
     *
     * @return string
     */
    public function tagQuery($tag, $content)
    {
        $tag['id']    = $tag['id'] ?? 'item';
        $tag['empty'] = ! empty($tag['empty']) ? $tag['empty'] : '';
        $tag['cache'] = ! empty($tag['cache']) && is_numeric($tag['cache']) ? intval($tag['cache']) : 3600;
        $tag['key']   = empty($tag['key']) ? '' : 'key="'.$tag['key'].'"';
        $tag['mod']   = isset($tag['mod']) && is_numeric($tag['mod']) ? 'mod="'.$tag['mod'].'"' : '';

        if (empty($tag['sql']) && empty($tag['table'])) {
            return '';
        }

        $parseStr = '<?php'."\r\n";
        $parseStr .= '$__QUERY__ = (new \app\index\taglib\huicms\TagQuery())->query('.self::arrToHtml($tag).');'."\r\n";
        $parseStr .= '?>';

        $parseStr .= '{volist name="__QUERY__" id="'.$tag['id'].'" '.$tag['key'].' '.$tag['mod'].' empty="'.$tag['empty'].'"}';
        if ($tag['mod']) {
            $parseStr .= '{php}$mod=$mod+1;{/php}';
        }
        $parseStr .= $content;
        $parseStr .= '{/volist}';

        return $parseStr;
    }

    /**
     * 筛选标签
     * currentstyle-选择的class,multiple-允许多选,field-指定字段，多个使用英文逗号分隔,alltxt-指定第一个选项的文字，默认“全部”，若指定为off，则不显示。
     *
     * @param $tag
     * @param $content
     *
     * @return string
     */
    public function tagFilter($tag, $content)
    {
        $tag['id']           = ! empty($tag['id']) ? $tag['id'] : 'item';
        $tag['currentstyle'] = ! empty($tag['currentstyle']) ? $tag['currentstyle'] : 'active';  // 选中的class
        $tag['multiple']     = isset($tag['multiple']) && $tag['multiple'] == 1 ? 1 : 0;  // 是否多选
        $tag['field']        = ! empty($tag['field']) ? $tag['field'] : '';
        $tag['alltxt']       = ! empty($tag['alltxt']) ? $tag['alltxt'] : "全部";

        $parseStr = '<?php'."\r\n";
        $parseStr .= '$__FILTERLIST__ = [];'."\r\n";
        $parseStr .= 'if (isset($model_id)):'."\r\n";
        $parseStr .= '$__FILTERLIST__ = (new \app\index\taglib\huicms\TagFilter())->lists($model_id, '.self::arrToHtml($tag).');'."\r\n";
        $parseStr .= 'endif;'."\r\n";
        $parseStr .= '?>';
        $parseStr .= '{volist name="__FILTERLIST__" id="'.$tag['id'].'" }';
        $parseStr .= $content;
        $parseStr .= '{/volist}';

        return $parseStr;
    }

    /**
     * 转换数据为HTML代码
     *
     * @param $data
     *
     * @return string
     */
    private static function arrToHtml($data)
    {
        if (is_array($data)) {
            $str = '[';
            foreach ($data as $key => $val) {
                if (is_array($val)) {
                    $str .= "'$key'=>".self::arrToHtml($val).",";
                } else {
                    //如果是变量的情况
                    if (is_int($val)) {
                        $str .= "'$key'=>$val,";
                    } else {
                        if (is_null($val)) {
                            $str .= "'$key'=>null,";
                        } else {
                            if (strpos($val, '$') === 0) {
                                $str .= "'$key'=>$val,";
                            } else {
                                if (preg_match("/^([a-zA-Z_].*)\(/i", $val, $matches)) {//判断是否使用函数
                                    if (function_exists($matches[1])) {
                                        $str .= "'$key'=>$val,";
                                    } else {
                                        $str .= "'$key'=>'".self::newAddslashes($val)."',";
                                    }
                                } else {
                                    $str .= "'$key'=>'".self::newAddslashes($val)."',";
                                }
                            }
                        }
                    }
                }
            }
            $str = rtrim($str, ',');

            return $str.']';
        }

        return '';
    }

    /**
     * 返回经addslashes处理过的字符串或数组
     *
     * @param string $string 需要处理的字符串或数组
     *
     * @return mixed
     */
    private static function newAddslashes($string)
    {
        if ( ! is_array($string)) {
            return addslashes($string);
        }
        foreach ($string as $key => $val) {
            $string[$key] = self::newAddslashes($val);
        }

        return $string;
    }

}
